import json
import os

from flow_alchemy.util.log_item import SetattrItem, LogItem
from flow_alchemy.util.serializable import Serializable


class LogManage(Serializable):

    def __init__(self):
        self._stack = []
        self._items = []
        # self.counter = 0

    def push(self, obj):
        self._stack.append(obj)
        return self._stack

    def pop(self):
        item = self._stack.pop()
        if item:
            top = self.top
            if top:
                if not self.top.end_date:
                    self.top.end()
                self.top.add_pair(item.name, item.to_dict())
            else:
                self._items.append(item.to_dict())
            return item
        else:
            return None

    @property
    def top(self):
        try:
            return self._stack[-1]
        except (AttributeError, IndexError):
            return None

    def make_item(self, name, t='LogItem'):
        item = LogItem(name=name, manage=self, t=t)
        self.push(item)
        return item

    def make_function(self, name):
        item = LogItem(name=name, manage=self, t='FunctionItem')
        self.push(item)
        return item

    def make_exception(self, name):
        item = LogItem(name=name, manage=self, t='ExceptionItem')
        self.push(item)
        return item

    def make_setattr(self, obj):
        item = SetattrItem(obj, manage=self)
        self.push(item)
        return item

    def write(self, tid, directory, create_date):

        while self.top:
            self.pop()

        if not os.path.exists(directory):
            os.makedirs(directory)
        path = os.sep.join([directory, str(tid) + '@' + create_date.strftime('%Y-%m-%d %H-%M-%S') + '.json'])
        with open(path, 'w+', encoding='utf-8') as f:
            json.dump(self._items, f, indent=4)
        self._stack.clear()
        self._items.clear()
        return path

    def to_dict(self):
        return {'items': self._items}
